/*
 * @Date: 2023-04-13 19:53:29
 * @LastEditors: Dannycjh 2233879049@qq.com
 * @LastEditTime: 2023-04-28 09:31:54
 */
import { _decorator, Button, Component, director, Input, isValid, Node, Scene } from 'cc';
import { App } from '../App';
import { EventConst } from '../common/Common';
const { ccclass, property } = _decorator;
import * as fgui from "fairygui-cc";
import UtilTool from './UtilTool';

@ccclass('onClick')
export class onClick extends Component {
    private static instance: any = null;
    private static listenerArray: any = [];
    public static getInstance<T>(c: { new(): T }): T {
        if (this.instance == null) {
            this.instance = new c();
        }
        return this.instance;
    }

    public static destroyInstance<T>(c: { new(): T }): void {
        if (this.instance) {
            this.instance = null;
        }
    }

    /**
     * 添加on监听
     * @param target            脚本组件
     * @param callFunc          函数
     * @param that              this上下文
     * @param emitData          传递数据
     * @param isNeedPlayAudio   是否播放点击音效，默认false
     * @param eventName         事件名，默认"click"
     * @param delayTime         按钮防抖时间
     * @param isNeedDelay       是否需要等待(节流)
     */
    public addButtonClickEvent(target: any, callFunc: Function, that: any, emitData: any = null, isNeedPlayAudio: boolean = false, eventName?: string, delayTime?: number, isNeedDelay?: number) {
        if (!target?.node) return;
        if (isValid(target.node)) {
            eventName = eventName || Node.EventType.TOUCH_START;//默认事件名为click
            if (isNeedDelay) {
                
                target.node.on(eventName, this.throttle(callFunc, that, emitData, isNeedPlayAudio, isNeedDelay), that);
            } else if (delayTime) {
                target.node.on(eventName, this.debounce(callFunc, that, emitData, isNeedPlayAudio, delayTime), that);
            } else {
                // UtilTool.printLog(target?.hasClickListener(),'是否有点击事件');
                
                if (target.onClick) {
                    target.onClick(()=>{
                        !!isNeedPlayAudio && App.Audio.playOneShot("click",true);
                        callFunc.call(that, emitData);
                    })
                }else{
                    target.node.on(eventName, () => {
                        !!isNeedPlayAudio && App.Audio.playOneShot("click",true);
                        callFunc.call(that, emitData);
                    }, target);
                };
            }
        }
        onClick.listenerArray.push(target)
    }

    /**
     * 按钮节流 方法一  原理：从首次点击开始计时，间隔指定时间后执行
     * **/
    public throttle(callFunc: Function, that: any, emitData?: any, isNeedPlayAudio?: boolean, isNeedDelay?: number) {
        let prev = 0 //Date.now(); // 首次初始化的时候prev的值改为0，因为初始化后不需要间隔这个时间后才可以点击
        let delay = isNeedDelay;
        return function () {
            var now = Date.now();
            if (prev==0 || (now - prev >= delay)) {
                !!isNeedPlayAudio && App.Audio.playOneShot("click",true);
                callFunc.call(that, emitData);
                prev = Date.now();
            }
        }
    }

    /**
        * 按钮防抖 方法二  原理：从最后一次点击开始计时，到达指定时间后执行
        * **/
    public debounce(callFunc: Function, that: any, emitData?: any, isNeedPlayAudio?: boolean, delayTime?: number,) {
        var timer = null;
        return function () {
            // 清除已存在的定时器
            timer && clearTimeout(timer)
            timer = setTimeout(function () {
                !!isNeedPlayAudio && App.Audio.playOneShot("click",true);
                callFunc.call(that, emitData);
            }, delayTime);
        }
    }

    /**移除on监听*/
    public removeButtonClickEvent(target: any, eventName?: string) {
        if (!target?.node) return;
        eventName = eventName || Node.EventType.TOUCH_START;//默认事件名为click
        if (isValid(target.node)) {
            target.node.off(eventName);
        }
    }
    // onClick.listenerArray.push(target)
    public removeButtonClickEventAll(){ //移除监听到的所有点击事件
        UtilTool.printLog(onClick.listenerArray,'onClick.listenerArray');
        
        onClick.listenerArray.forEach((item:Node|any )=>{
            UtilTool.printLog(item.name);
            
            if (!item._node || !isValid(item)) {
                return;
            }
            if (item.onClick) {
                item.clearClick()
            }else{
                UtilTool.printLog(item,'item');
                
                item.off(Node.EventType.TOUCH_START)
            }
        })
        onClick.listenerArray = [];
    }
    start() {

    }

    update(deltaTime: number) {

    }
}